//
// Created by yangy on 2018/6/28.
//

#include "JavaCallBack.h"


JavaCallBack::JavaCallBack(JavaVM *javaVM, JNIEnv *env, jobject listener_obj) {
    this->env = env;
    this->javaVM = javaVM;
    this->listener_obj = listener_obj;

    jclass prepare_cls = env->GetObjectClass(listener_obj);
    if (prepare_cls == NULL) {
        return;
    }

    this->prepare_mid = env->GetMethodID(prepare_cls, "onPrepared", "()V");
    this->load_mid = env->GetMethodID(prepare_cls,"onLoad","(Z)V");
    this->time_info_mid = env->GetMethodID(prepare_cls,"timeInfo","(II)V");
    this->error_mid = env->GetMethodID(prepare_cls,"onError","(ILjava/lang/String;)V");
    this->record_mid = env->GetMethodID(prepare_cls,"encodePCM2AAC","(I[B)V");
    if (prepare_mid == NULL){
        return;
    }
}

JavaCallBack::~JavaCallBack() {

}

void JavaCallBack::onPrepared(int type) {
    if(type == MAIN_THREAD){
        env->CallVoidMethod(listener_obj, prepare_mid);
    } else if (type == CHILD_THREAD){
        JNIEnv *env1;
        this->javaVM->AttachCurrentThread(&env1,NULL);
        env1->CallVoidMethod(listener_obj,prepare_mid);
        this->javaVM->DetachCurrentThread();
    }
}

void JavaCallBack::onLoad(int type, bool load) {
    if(type == MAIN_THREAD){
        env->CallVoidMethod(listener_obj, load_mid,load);
    } else if (type == CHILD_THREAD){
        JNIEnv *env1;
        this->javaVM->AttachCurrentThread(&env1,NULL);
        env1->CallVoidMethod(listener_obj, load_mid,load);
        this->javaVM->DetachCurrentThread();
    }
}

void JavaCallBack::onTimeInfo(int type, int total, int current) {
    if(type == MAIN_THREAD){
        env->CallVoidMethod(listener_obj, time_info_mid,total,current);
    } else if (type == CHILD_THREAD){
        JNIEnv *env1;
        this->javaVM->AttachCurrentThread(&env1,NULL);
        env1->CallVoidMethod(listener_obj, time_info_mid,total,current);
        this->javaVM->DetachCurrentThread();
    }
}

void JavaCallBack::onError(int type, int code, char *msg) {
    if(type == MAIN_THREAD){
        jstring j_msg = env->NewStringUTF(msg);
        env->CallVoidMethod(listener_obj, error_mid,code,j_msg);
        env->DeleteLocalRef(j_msg);
    } else if (type == CHILD_THREAD){
        JNIEnv *env1;
        this->javaVM->AttachCurrentThread(&env1,NULL);
        jstring j_msg = env1->NewStringUTF(msg);
        env1->CallVoidMethod(listener_obj, error_mid,code,j_msg);
        env1->DeleteLocalRef(j_msg);
        this->javaVM->DetachCurrentThread();
    }
}

void JavaCallBack::onRecord(int type, int size, void *buffer) {
    if(type == MAIN_THREAD){
        jbyteArray jbyteArray1 = env->NewByteArray(size);
        env->SetByteArrayRegion(jbyteArray1, 0, size,static_cast<const jbyte *>(buffer));
        env->CallVoidMethod(listener_obj, record_mid,size,jbyteArray1);
        env->DeleteLocalRef(jbyteArray1);
    } else if (type == CHILD_THREAD){
        JNIEnv *env1;
        this->javaVM->AttachCurrentThread(&env1,NULL);
        jbyteArray jbyteArray1 = env1->NewByteArray(size);
        env1->SetByteArrayRegion(jbyteArray1, 0, size,static_cast<const jbyte *>(buffer));
        env1->CallVoidMethod(listener_obj, record_mid,size,jbyteArray1);
        env1->DeleteLocalRef(jbyteArray1);
        this->javaVM->DetachCurrentThread();
    }
}
